class Member < ActiveRecord::Base

  has_many :attendance_records, :conditions => {:waitlist => false}
  has_many :events, :through => :attendance_records
  has_many :positions
  has_many :announcements

  validates_presence_of :first_name
  validates_presence_of :last_name
  validates_presence_of :username
  validates_presence_of :password

  def full_name
    "#{first_name} #{last_name}"
  end

  def last_first
    "#{last_name}, #{first_name}"
  end

  def self.authenticate(username, password)
    Member.find_by_username_and_password(username, hash_password(password))
  end

  def self.hash_password(password)
    Digest::SHA1.hexdigest(password)
  end

  def self.semester(date)
    if (date.month > 6)
      "Fall #{date.year}"
    else
      "Spring #{date.year}"
    end
  end

  #Actives
  def self.active_service_requirement
    24
  end

  def self.active_fellowships_requirement
    4
  end

  def self.active_leaderships_requirement
    10
  end

  def self.active_fundraisers_requirement
    2
  end

  def self.active_meetings_requirement
    20
  end

  def self.active_dues_requirement
    2
  end

  # Pledges
  def self.pledge_service_requirement
    20
  end

  def self.pledge_fellowships_requirement
    4
  end

  def self.pledge_leaderships_requirement
    6
  end

  def self.pledge_fundraisers_requirement
    1
  end

  def self.pledge_meetings_requirement
    16
  end

  def self.pledge_dues_requirement
    2
  end

  def self.pledge_reqs_requirement
    9
  end

  def self.get_adjustment_hours(memberID, eventID)
    record = AttendanceRecord.find(:all, :conditions => {:event_id => "#{eventID}", :member_id => "#{memberID}"})
    if (record.size > 0)
      if record[0].adjustment_hours.nil?
        record[0].adjustment_hours = 0.0
        record[0].save
      end
      return record[0].adjustment_hours
    else
      return 0
    end
  end

  def self.getData(member, semester)
    data = {
      "dues" => 0,
      "fellowship" => {"potential" => 0, "actual" => 0},
      "fundraiser" => {"potential" => 0, "actual" => 0},
      "hours" => {"potential" => 0, "actual" => 0},
      "leadership" => {"potential" => 0, "actual" => 0},
      "meeting" => {"potential" => 0, "actual" => 0},
      "percent" => 0,
      "pledge_req" => {"potential" => 0, "actual" => 0},
      "service" => {"potential" => 0, "actual" => 0},
      "total_hours" => 0,
      "total_required_hours" => 0
    }

    if(member.up_to_date == true)
      get_stored_data(member, data)
    else
      if member.status == "Active" or member.status == "Probate" or member.status == "Associate" or
        member.status == "Neophyte" or member.status == "New Active" or member.status == "Pledge"

        potential_indy_hours = 0
        actual_indy_hours = 0
        penalty = 0
        now = Time.now

        memberEvents = member.events.find_all_by_semester_index_and_deleted(semester, false)
        memberEvents.each do |event|
          currentAR = member.attendance_records.find_by_event_id_and_waitlist(event.id, false)
          unless currentAR.nil?
            if currentAR.attended == false and event.approved == true and event.event_type != "Committee"
              if event.event_type == "Service" and member.status != "Neophyte" and member.status != "Pledge"
                penalty += event.additional_service_hours / 2
              end
            else
              if currentAR.adjustment_hours.nil?
                currentAR.adjustment_hours = 0.0
                currentAR.save
              end

              if event.event_type != "Indy Hours" and event.event_type != "Dues" and event.event_type != "Dues (late)"
                handle_attendance_record(member, data, event, currentAR, now)
              elsif event.event_type == "Dues"
                data["dues"] += 1
              elsif event.event_type == "Dues (late)"
                penalty += 1
                data["dues"] += 1
              else
                potential_indy_hours += event.hours + currentAR.adjustment_hours
                if event.approved == true and event.date < now
                  actual_indy_hours += event.hours + currentAR.adjustment_hours
                end
              end
            end
          end
        end

        if member.status == "Active" or member.status == "New Active" or
           member.status == "Probate" or member.status == "Associate"
          if potential_indy_hours > 10
            data["service"]["potential"] += 10
          else
            data["service"]["potential"] += potential_indy_hours
          end
          if actual_indy_hours > 10
            data["service"]["actual"] += 10
          else
            data["service"]["actual"] += actual_indy_hours
          end
        elsif member.status == "Neophyte" or member.status == "Pledge"
          if potential_indy_hours > 6
            data["service"]["potential"] += 6
          else
            data["service"]["potential"] += potential_indy_hours
          end
          if actual_indy_hours > 6
            data["service"]["actual"] += 6
          else
            data["service"]["actual"] += actual_indy_hours
          end
        end

        data["total_required_hours"] = calculate_total_hours(member, penalty)

#        dataReturn[9] = percent_done(member, dataReturn)

        set_stored_data(member, data)

        office = member.positions.find_by_semester_index(semester)
        member.office = !office.nil? ? Position.getPosition(office.position) : nil

        member.up_to_date = true
        member.save
      end
    end

    return data
  end

  def self.get_stored_data(member, data)
    data["service"]["potential"] = member.stored_potential_service_hours
    data["fellowship"]["potential"] = member.stored_potential_fellowships
    data["leadership"]["potential"] = member.stored_potential_leaderships
    data["fundraiser"]["potential"] = member.stored_potential_fundraisers
    data["meeting"]["potential"] = member.stored_potential_active_meetings
    data["pledge_req"]["potential"] = member.stored_potential_pledge_reqs
#    data["percent"] = member.stored_percent_done
    data["service"]["actual"] = member.stored_service_hours
    data["fellowship"]["actual"] = member.stored_fellowships
    data["leadership"]["actual"] = member.stored_leaderships
    data["fundraiser"]["actual"] = member.stored_fundraisers
    data["dues"] = member.stored_dues
    data["meeting"]["actual"] = member.stored_active_meetings
    data["total_required_hours"] = member.stored_total_hours
    data["pledge_req"]["actual"] = member.stored_pledge_reqs
  end

  def self.set_stored_data(member, data)
    member.stored_potential_service_hours = data["service"]["potential"]
    member.stored_potential_fellowships = data["fellowship"]["potential"]
    member.stored_potential_leaderships = data["leadership"]["potential"]
    member.stored_potential_fundraisers = data["fundraiser"]["potential"]
    member.stored_potential_active_meetings = data["meeting"]["potential"]
    member.stored_potential_pledge_reqs = data["pledge_req"]["potential"]
#        member.stored_percent_done = dataReturn[9]
    member.stored_service_hours = data["service"]["actual"]
    member.stored_fellowships = data["fellowship"]["actual"]
    member.stored_leaderships = data["leadership"]["actual"]
    member.stored_fundraisers = data["fundraiser"]["actual"]
    member.stored_dues = data["dues"]
    member.stored_active_meetings = data["meeting"]["actual"]
    member.stored_total_hours = data["total_required_hours"]
    member.stored_pledge_reqs = data["pledge_req"]["actual"]
  end

  def self.handle_attendance_record(member, data, event, currentAR, now)
    data["service"]["potential"] += event.additional_service_hours + currentAR.adjustment_hours
    data["fellowship"]["potential"] += event.additional_fellowships
    data["leadership"]["potential"] += event.additional_leaderships
    data["fundraiser"]["potential"] += event.additional_fundraisers
    data["meeting"]["potential"] += event.additional_active_meetings
    if event.approved == true and event.date < now
      data["service"]["actual"] += event.additional_service_hours + currentAR.adjustment_hours
      data["fellowship"]["actual"] += event.additional_fellowships
      data["leadership"]["actual"] += event.additional_leaderships
      data["fundraiser"]["actual"] += event.additional_fundraisers
      data["meeting"]["actual"] += event.additional_active_meetings
    end

    if event.event_type != "Pledge Meeting" and event.event_type != "Pledge Req" and event.event_type != "Active Meeting" and event.event_type != "Office Hour" and event.event_type != "Dues" and event.event_type != "Ceremony"
      if event.mic_id == member.id
        data["leadership"]["potential"] += 1
        if event.approved == true and event.date < now
          data["leadership"]["actual"] += 1
        end
      end
      if currentAR.driver == true
        data["service"]["potential"] += 0.5
        if event.approved == true and event.date < now
          data["service"]["actual"] += 0.5
        end
      end
    end

    if event.event_type == "Pledge Req" and (member.status == "Pledge" or member.status == "Neophyte")
      data["pledge_req"]["potential"] += 1
      if event.approved == true and event.date < now
        data["pledge_req"]["actual"] += 1
      end
    end
  end

  #dataReturn[0] = potential_service_hours
  #dataReturn[1] = potential_fellowships
  #dataReturn[2] = potential_leaderships
  #dataReturn[3] = potential_fundraisers
  #dataReturn[4] = potential_office_hours
  #dataReturn[5] = potential_ceremonies
  #dataReturn[6] = potential_sets_of_dues_paid
  #dataReturn[7] = potential_active_meetings_attended
  #dataReturn[8] =
  #dataReturn[9] = percent_done
  #dataReturn[10] = actual_service_hours
  #dataReturn[11] = actual_fellowships
  #dataReturn[12] = actual_leaderships
  #dataReturn[13] = actual_fundraisers
  #dataReturn[14] = actual_office_hours
  #dataReturn[15] = actual_ceremonies
  #dataReturn[16] = actual_sets_of_dues_paid
  #dataReturn[17] = actual_active_meetings_attended
  #dataReturn[18] = total_hours_required
  #datareturn[19] = potential_service_back_completed
  #dataReturn[20] = potential_pledge_reqs
  #dataReturn[21] = actual_pledge_reqs
  #dataReturn[22] = service_back_total
  #dataReturn[23] = service_back_completed
  def self.percent_done(member, dataReturn)
    if member.status == "Active" or member.status == "New Active" or member.status == "Associate" or member.status == "Probate"
      done = dataReturn[10] > dataReturn[18] ? dataReturn[18] : dataReturn[10]
      done += dataReturn[11] > active_fellowships_requirement ? active_fellowships_requirement : dataReturn[11]
      done += dataReturn[12] > active_leaderships_requirement ? active_leaderships_requirement : dataReturn[12]
      done += dataReturn[13] > active_fundraisers_requirement ? active_fundraisers_requirement : dataReturn[13]
      done += dataReturn[14] > active_office_hours_requirement ? active_office_hours_requirement : dataReturn[14]
      done += dataReturn[15] > active_ceremonies_requirement ? active_ceremonies_requirement : dataReturn[15]
      done += dataReturn[16] > active_dues_requirement ? active_dues_requirement : dataReturn[16]
      done += dataReturn[23] > dataReturn[22] ? dataReturn[22] : dataReturn[23]
      out_of = dataReturn[18] + active_fellowships_requirement + active_leaderships_requirement +
              active_fundraisers_requirement + active_office_hours_requirement + active_ceremonies_requirement +
              active_dues_requirement + dataReturn[22]
    elsif member.status == "Pledge" or member.status == "Neophyte"
      done = dataReturn[10] > dataReturn[18] ? dataReturn[18] : dataReturn[10]
      done += dataReturn[11] > pledge_fellowships_requirement ? pledge_fellowships_requirement : dataReturn[11]
      done += dataReturn[12] > pledge_leaderships_requirement ? pledge_leaderships_requirement : dataReturn[12]
      done += dataReturn[13] > pledge_fundraisers_requirement ? pledge_fundraisers_requirement : dataReturn[13]
      done += dataReturn[14] > pledge_office_hours_requirement ? pledge_office_hours_requirement : dataReturn[14]
      done += dataReturn[15] > pledge_ceremonies_requirement ? pledge_ceremonies_requirement : dataReturn[15]
      done += dataReturn[16] > pledge_dues_requirement ? pledge_dues_requirement : dataReturn[16]
      done += dataReturn[17] > pledge_meetings_requirement ? pledge_meetings_requirement : dataReturn[17]
      done += dataReturn[21] > pledge_reqs_requirement ? pledge_reqs_requirement : dataReturn[21]
      done += dataReturn[23] > dataReturn[22] ? dataReturn[22] : dataReturn[23]
      out_of = dataReturn[18] + pledge_fellowships_requirement + pledge_leaderships_requirement +
              pledge_fundraisers_requirement + pledge_office_hours_requirement + pledge_ceremonies_requirement +
              pledge_dues_requirement + pledge_meetings_requirement + pledge_reqs_requirement + dataReturn[22]
    else
      done = 0
      out_of = 1
    end
    return (done / out_of * 100).to_i
  end

  def self.calculate_total_hours(member, penalty)
    memberTotalHours = 0
    if member.status == "Active" or member.status == "New Active" or member.status == "Associate" or member.status == "Probate"
      memberTotalHours = active_service_requirement + penalty
    elsif member.status == "Pledge" or member.status == "Neophyte"
      memberTotalHours = pledge_service_requirement
    end
  end

  def self.get_committee(member, semester)
    member.events.find_by_semester_index_and_event_type_and_deleted(semester, "Committee", false)
  end

  def self.get_quorum(member)
    dataReturn = getData(member, Event.getCurrentSemester)
#    return dataReturn[9] >= 75 ? "Yes" : "No"
    eligible = "Yes"
    dataReturn[10] < dataReturn[18] ? eligible = "No" : nil
    dataReturn[11] < Member.active_fellowships_requirement ? eligible = "No" : nil
    dataReturn[12] < Member.active_leaderships_requirement ? eligible = "No" : nil
    dataReturn[13] < Member.active_fundraisers_requirement ? eligible = "No" : nil
    dataReturn[14] < Member.active_office_hours_requirement ? eligible = "No" : nil
    dataReturn[15] < 1 ? eligible = "No" : nil
    dataReturn[16] < Member.active_dues_requirement ? eligible = "No" : nil
    dataReturn[23] < dataReturn[22] ? eligible = "No" : nil
    return eligible
#    total = dataReturn[10] + dataReturn[11] + dataReturn[12] + dataReturn[13] + dataReturn[14] + dataReturn[16]
#    if total >= 10
#      return "Yes"
#    else
#      return "No"
#    end
  end

  def self.get_career_hours(members)
    dataReturn = Array.new(members.size)

    members.each_with_index do |member, index|
      total = 0
      memberEvents = member.events.find_all_by_deleted(false)
      memberEvents.each do |event|
        currentAR = member.attendance_records.find_by_event_id_and_waitlist_and_deleted(event.id, false, false)
        unless currentAR.nil?
          if currentAR.attended == true and event.approved == true and event.date < Time.now
            if event.event_type == "Service" or event.event_type == "Indy Hours"
              total += event.hours
            end
            total += event.additional_service_hours
            if !currentAR.adjustment_hours.nil?
              total += currentAR.adjustment_hours
            end
          end
        end
      end
      dataReturn[index] = total
    end

    return dataReturn
  end

  #service, fellowship, leadership
  def self.get_year_hours(members)
    dataReturn = Array.new(3,0)

    members.each_with_index do |member, index|
      memberEvents = member.events.find_all_by_deleted(false, :conditions => "semester_index = #{Event.getCurrentSemester} OR semester_index = #{Event.getCurrentSemester - 1}")
      memberEvents.each do |event|
        currentAR = member.attendance_records.find_by_event_id_and_waitlist_and_deleted(event.id, false, false)
        unless currentAR.nil?
          if currentAR.attended == true and event.approved == true and event.date < Time.now
            if event.event_type == "Service" or event.event_type == "Indy Hours"
              dataReturn[0] += event.hours
              if !currentAR.adjustment_hours.nil?
                dataReturn[0] += currentAR.adjustment_hours
              end
            elsif event.event_type == "Leadership"
              dataReturn[2] += 1
            elsif event.event_type == "Fellowship"
              dataReturn[1] += 1
            end
            dataReturn[0] += event.additional_service_hours
            dataReturn[1] += event.additional_fellowships
            dataReturn[2] += event.additional_leaderships
          end
        end
      end
    end

    return dataReturn
  end

end
